
算法特化的方法是通过唯一“标记”来识别不同的实现，为了处理advanceIter()的问题，可以使用标准库的迭代器类别标签类型(定义如下)来识别advanceIter()算法的两个实现变体:

\begin{lstlisting}[style=styleCXX]
template<typename Iterator, typename Distance>
void advanceIterImpl(Iterator& x, Distance n, std::input_iterator_tag)
{
	while (n > 0) { // linear time
		++x;
		--n;
	}
}

template<typename Iterator, typename Distance>
void advanceIterImpl(Iterator& x, Distance n,
					std::random_access_iterator_tag) {
	x += n; // constant time
}
\end{lstlisting}

advanceIter()函数模板只是简单地转发参数和相应的标签:

\begin{lstlisting}[style=styleCXX]
template<typename Iterator, typename Distance>
void advanceIter(Iterator& x, Distance n)
{
	advanceIterImpl(x, n,
				typename
						std::iterator_traits<Iterator>::iterator_category());
}
\end{lstlisting}

特征类std::iterator\_traits通过其成员类型iterator\_category为迭代器提供了一个类别。迭代器类别是前面提到的\_tag类型之一，其指定了迭代器类型的类型。C++标准库中，可用的标签定义如下，使用继承来反映标签描述类别是从另一个标签派生而来的:

\begin{tcolorbox}[colback=webgreen!5!white,colframe=webgreen!75!black]
\hspace*{0.75cm}类别反映了概念，概念的继承称为精炼。在附录E中详细介绍了概念和精炼。
\end{tcolorbox}

\begin{lstlisting}[style=styleCXX]
namespace std {
	struct input_iterator_tag { };
	struct output_iterator_tag { };
	struct forward_iterator_tag : public input_iterator_tag { };
	struct bidirectional_iterator_tag : public forward_iterator_tag { };
	struct random_access_iterator_tag : public bidirectional_iterator_tag { };
}
\end{lstlisting}

利用标签调度的关键在于标签之间的关系。advanceIterImpl()的两个变体标记为std::input\_iterator\_tag和std::random\_access\_iterator\_tag，并且std::random\_access\_iterator\_tag继承自std::input\_iterator\_tag，所以使用随机访问迭代器调用advanceIterImpl()时，普通函数都会优先使用更特化的算法版本(使用std::random\_access\_iterator\_tag)。标签调度依赖于从单一的、主要的函数模板委派到一组\_impl变体，对这些变体进行标记，这样普通的函数重载将选择适用于给定模板参数最特化的算法。

当算法使用的属性具有体系结构，以及提供这些标记值的现有特征集时，标签调度工作得很好。当算法特化依赖于特定的类型属性时，就不那么方便了，比如类型T是否具有普通的复制赋值操作符。因此，我们需要更强大的技术。



































